// var fs = require('fs');
var fs = require('fs-extra');//先安装 npm install fs-extra
var path = require('path');
var crypto = require('crypto');

//热更新包远程地址
var remoteUrl = `https://xglxs.26joy.com/Upload/xyx/hotUpdate/shj/remote-assets`;
var version = `1.0.0`;

var manifest = {
    packageUrl: `${remoteUrl}${version}/`,
    remoteManifestUrl: `${remoteUrl}${version}/project.manifest`,
    remoteVersionUrl: `${remoteUrl}${version}/version.manifest`,
    version: version,
    assets: {},
    searchPaths: []
};

//生成的manifest文件存放位置地址
var dest = './assets/';

//默认构建发布出的项目地址
var src = './build/windows-debug/assets/';

//热更新文件
var remoteDir = `./packages-hot-update/`;

// Parse arguments 解析参数
var i = 2;
while (i < process.argv.length) {
    var arg = process.argv[i];

    switch (arg) {
        case '--url':
        case '-u':
            remoteUrl = process.argv[i + 1];
            manifest.packageUrl = `${remoteUrl}${version}/`;
            manifest.remoteManifestUrl = `${remoteUrl}${version}/project.manifest`;
            manifest.remoteVersionUrl = `${remoteUrl}${version}/version.manifest`;
            i += 2;
            break;
        case '--version':
        case '-v':
            version = process.argv[i + 1];
            manifest.version = version;
            manifest.packageUrl = `${remoteUrl}${version}/`;
            manifest.remoteManifestUrl = `${remoteUrl}${version}/project.manifest`;
            manifest.remoteVersionUrl = `${remoteUrl}${version}/version.manifest`;
            i += 2;
            break;
        case '--src':
        case '-s':
            src = process.argv[i + 1];
            i += 2;
            break;
        case '--dest':
        case '-d':
            dest = process.argv[i + 1];
            i += 2;
            break;
        default:
            i++;
            break;
    }
}


function readDir(dir, obj) {
    var stat = fs.statSync(dir);
    if (!stat.isDirectory()) {
        return;
    }
    var subPaths = fs.readdirSync(dir), subpath, size, md5, compressed, relative;
    for (var i = 0; i < subPaths.length; ++i) {
        if (subPaths[i][0] === '.') {
            continue;
        }
        subpath = path.join(dir, subPaths[i]);
        stat = fs.statSync(subpath);
        if (stat.isDirectory()) {
            readDir(subpath, obj);
        }
        else if (stat.isFile()) {
            // Size in Bytes
            size = stat['size'];
            md5 = crypto.createHash('md5').update(fs.readFileSync(subpath)).digest('hex');
            compressed = path.extname(subpath).toLowerCase() === '.zip';

            relative = path.relative(src, subpath);
            relative = relative.replace(/\\/g, '/');
            relative = encodeURI(relative);
            obj[relative] = {
                'size': size,
                'md5': md5
            };
            if (compressed) {
                obj[relative].compressed = true;
            }
        }
    }
}

var mkdirSync = function (path) {
    try {
        fs.mkdirSync(path);
    } catch (e) {
        if (e.code != 'EEXIST') throw e;
    }
}

// Iterate assets and src folder
readDir(path.join(src, 'src'), manifest.assets);
readDir(path.join(src, 'assets'), manifest.assets);

var destManifest = path.join(dest, 'project.manifest');
var destVersion = path.join(dest, 'version.manifest');

mkdirSync(dest);

var copyDir = `${remoteDir}remote-assets${version}/`;

fs.copy(path.join(src, 'src'), path.join(copyDir, 'src'), (err) => {
    if (err) throw err;
    console.log('src successfully copy');
});

fs.copy(path.join(src, 'assets'), path.join(copyDir, 'assets'), (err) => {
    if (err) throw err;
    console.log('assets successfully copy');
});

fs.writeFile(destManifest, JSON.stringify(manifest), (err) => {
    if (err) throw err;
    console.log('Manifest successfully generated');

    fs.copyFile(destManifest, path.join(copyDir, `project.manifest`), (err) => {
        if (err) throw err;
        console.log('Manifest successfully copy');
    });
});

delete manifest.assets;
delete manifest.searchPaths;
fs.writeFile(destVersion, JSON.stringify(manifest), (err) => {
    if (err) throw err;
    console.log('Version successfully generated');
    fs.copyFile(destVersion, path.join(copyDir, `version.manifest`), (err) => {
        if (err) throw err;
        console.log('Version successfully copy');
    });
});

/**
 * 检查main.js (不怎么必要)
 */
var mainPath = path.join(src, `main.js`)
var mainIs = fs.existsSync(mainPath);
if (mainIs) {
    var content = fs.readFileSync(mainPath).toString();
    if (content.indexOf(`jsb.fileUtils.setSearchPaths`) != -1) {
        console.log("main.js check successfully");
    }

    var add = `!function(){if("object"==typeof window.jsb){var e=localStorage.getItem("HotUpdateSearchPaths");if(e){var i=JSON.parse(e);jsb.fileUtils.setSearchPaths(i);var s=[],t=i[0]||"",l=t+"_temp/",r=l.length;jsb.fileUtils.isDirectoryExist(l)&&!jsb.fileUtils.isFileExist(l+"project.manifest.temp")&&(jsb.fileUtils.listFilesRecursively(l,s),s.forEach(e=>{var i=e.substr(r),s=t+i;"/"===e[e.length]?jsb.fileUtils.createDirectory(s):(jsb.fileUtils.isFileExist(s)&&jsb.fileUtils.removeFile(s),jsb.fileUtils.renameFile(e,s))}),jsb.fileUtils.removeDirectory(l))}}}();`
    content = add + content;
    fs.writeFile(mainPath, content, (err) => {
        if (err) throw err;
        console.log("main.js write successfully");
    });
} else {
    console.warn("Warn: main.js 文件不存在");
}